package com.ytjj.qmyx.admin.service.adapay;

import com.alibaba.fastjson.JSON;
import com.huifu.adapay.Adapay;
import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.core.util.AdapaySign;
import com.huifu.adapay.model.MerConfig;
import com.huifu.adapay.model.Refund;
import com.ytjj.qmyx.admin.constants.AdapayConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 
 * @describe 汇付天下 支付相关
 */
@Service
@Slf4j
@EnableConfigurationProperties(AdapayConstants.class)
public class AdaPayService {

    @Resource
    private AdapayConstants adapayConstants;

    /**
     * 初始化Adapay 支付配置信息
     * @param
     * @return void
     */
    public void initAdapayConfig(){
        try {
            log.info("=========初始化Adapay配置信息======");
            /**
             * debug 模式，开启后有详细的日志
             */
            Adapay.debug = true;

            /**
             * prodMode 模式，默认为生产模式，false可以使用mock模式
             */
            Adapay.prodMode = true;

            /**
             * 初始化商户配置，服务器启动前，必须通过该方式初始化商户配置完成
             * apiKey为prod模式的API KEY
             * mockApiKey为mock模式的API KEY
             * rsaPrivateKey为商户发起请求时，用于请求参数加签所需要的RSA私钥
             */
            String apiKey = adapayConstants.getAPI_KEY();
            String mockApiKey = adapayConstants.getMOCK_API_KEY();
            String rsaPrivateKey = adapayConstants.getRSA_PRIVATE_KEY();
            MerConfig merConfig = new MerConfig();
            merConfig.setApiKey(apiKey);
            merConfig.setApiMockKey(mockApiKey);
            merConfig.setRSAPrivateKey(rsaPrivateKey);
            Adapay.initWithMerConfig(merConfig);
        } catch (Exception e) {
            String error = String.format("Adapay配置初始化出错:%s",e.getMessage());
            log.info(error);
            new RuntimeException(error);
        }
    }

    /**
     * 执行一个退款交易
     *
     * @param paymentId 退款目标支付对象 id
     * @param refundAmt 退款金额，若退款金额小于原交易金额，则认为是部分退款，必须大于0，保留两位小数点，如0.10、100.05等
     * @param tradeNo 请求订单号，只能为英文、数字或者下划线的一种或多种组合
     * @return 创建的退款对象
     * @throws Exception 异常
     */
    public Map<String, Object> executeRefund( String paymentId,String refundAmt,String tradeNo){
        //Adapay退款响应
        Map<String, Object> response = new HashMap<>();
        try {
            log.info("=======execute refund begin=======");
            Map<String, Object> refundParams = new HashMap<String, Object>(2);
            //退款金额（必须大于 0），保留两位小数点，如0.10、100.05等
            refundParams.put("refund_amt", new BigDecimal(refundAmt).divide(new BigDecimal(100),2, RoundingMode.CEILING) );
            //应用的app_id
            refundParams.put("app_id", adapayConstants.getAPPID());
            //请求订单号，只能为英文、数字或者下划线的一种或多种组合
            refundParams.put("refund_order_no",tradeNo);
            //异步通知地址
            refundParams.put("notify_url",adapayConstants.getREFUND_NOTIFY_URL());
            log.info("退款请求参数：" + JSON.toJSONString(refundParams));
            response = Refund.create(paymentId, refundParams);
            log.info("退款返回参数：" + JSON.toJSONString(response));
            log.info("=======execute refund end=======");
        } catch (BaseAdaPayException e) {
            log.error("====订单:{},退款出错：{}======",tradeNo,e.getMessage());
        }
        return response;
    }

    /**
     * 查询adapay退款情况
     * @param paymentId Adapay生成的支付对象id，三者必传其一
     * @param refundId Adapay生成的退款对象id，三者必传其一
     * @param refundOrderNo 退款订单号
     * @return Map<String,Object>
     */
    public Map<String, Object> queryRefund( String paymentId,String refundId,String refundOrderNo) throws BaseAdaPayException {
        //Adapay退款响应
        Map<String, Object> refundParams = new HashMap<>(2);
        refundParams.put("payment_id", paymentId);
        Map<String, Object> refund = Refund.query(refundParams);
        return refund;
    }



    /**
     * Adapay 支付验签
     * @param request
     * @return boolean
     */
    public boolean checkSign(HttpServletRequest request) {
        //验签标记
        boolean checkSign = false;
        try {
            //验签请参data
            String data = request.getParameter("data");
            //验签请参sign
            String sign = request.getParameter("sign");
            //验签请参publicKey
            String publicKey = AdapayCore.PUBLIC_KEY;
            log.info("adapay验签请参：data={}sign={}", data, sign);
            //验签
            checkSign = AdapaySign.verifySign(data, sign, publicKey);
        } catch (Exception e) {
            checkSign = false;
            log.info("异步回调开始，参数，request={}");
        }
        return checkSign;
    }


}
